#include <GL/glew.h>
#include <FreeImage.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <time.h>
#include "objects.h"
#include "Game.h"

#include <windows.h>		// Header File For Windows
#include <stdarg.h>			// Header File For Variable Argument Routines
#include <GL/gl.h>			// Header File For The OpenGL32 Library
#include <GL/glu.h>			// Header File For The GLu32 Library
#include <AL/al.h>
#include <AL/alut.h>
#define NUMBER_OF_SOUNDS 25

/*
To do: 
	Fix:
		fix when width is smaller than height(parameter are correct for this but picking does not work properly)	

*/
#define ESC 27
#define SPACE 32
int Height=1000, Width=1412;

//audio
int playBirds = 0;
int playAvalanche = 0;
int playSnow = 0;
int playBunny = 0;
int playBunnyEat = 0;
int playHarvest = 0;
int playNight = 0;
int playPlantWilt = 0;
int playRain = 0;
int playRiver = 0;
int playWind = 0;
int playZoomIn = 0;
int playZoomOut = 0;
void play( int );
void stop (int);
void playAudio();
void setupAudio ();
ALuint buffers[NUMBER_OF_SOUNDS];
ALuint sources[NUMBER_OF_SOUNDS];
float vol = 0.0f;

int updateTimer = 20; //in ms
int drawPlant = 0;
int drawHouse = 1;
int harvesting = 0;
int drawSnow = 0;
int drawHarvest = 0;
int reset = 0;
int drawBunny = 0;
int score1;
int score10;
int drawTutorial = 0;

//functions prototypes for picking
void drawMenu();
void drawPlants();
void drawPic(objects);

//menus items
objects background;
objects waterCycleMenu;
objects shooterMenu;
objects title;

//water cycle objects
objects sun;
objects cloud;
objects tree;
objects rain;
objects mountain[2];
objects plant[4];
objects fish;
objects river;
objects steam[3];
objects wind;
objects sunBeam[3];
objects house[2];
objects person[2];
objects snow[4];
objects snowFlake;
objects avalanche;
objects harvest[2];
objects bunny[5];
objects tutorial[4];

//water cycle buttons
objects buttonBack;
objects button[2];
objects sunButton;
objects windButton;
objects collectButton;
objects rainButton;

//water cycle stats
objects statsLevel[4];
objects cloudStat;
objects windStat;
objects plantGrowthStat;
objects snowStat;

//water cycle score
objects scoreBack;
objects onesScore;
objects tensScore;
objects gameOver;

//for picking
#define BUFSIZE 512
GLuint selectBuf[BUFSIZE];
int pickName = 0;
int buttonName = 1;
int menuSelection = 0;

void play(int index)
{
    alSourcePlay (sources[index]);
}

void stop(int index)
{
    alSourceStop (sources[index]);
}

void setupAudio()
{
    std::string soundFiles[NUMBER_OF_SOUNDS];

    soundFiles[0] = "audio/birds1.wav";
    soundFiles[1] = "audio/birds2.wav";
    soundFiles[2] = "audio/birds3.wav";
    soundFiles[3] = "audio/birds4.wav";
    soundFiles[4] = "audio/bunny1.wav";
    soundFiles[5] = "audio/bunny2.wav";
    soundFiles[6] = "audio/harvest.wav";
    soundFiles[7] = "audio/night1.wav";
    soundFiles[8] = "audio/night2.wav";
    soundFiles[9] = "audio/night3.wav";
    soundFiles[10] = "audio/plantWilt.wav";
    soundFiles[11] = "audio/rain1.wav";
    soundFiles[12] = "audio/rain2.wav";
    soundFiles[13] = "audio/rain3.wav";
    soundFiles[14] = "audio/rain4.wav";
    soundFiles[15] = "audio/rain5.wav";
    soundFiles[16] = "audio/wind1.wav";//not working
    soundFiles[17] = "audio/wind2.wav";
    soundFiles[18] = "audio/zoomIn.wav";
    soundFiles[19] = "audio/zoomOut.wav";
    soundFiles[20] = "audio/chomp1.wav";
    soundFiles[21] = "audio/chomp2.wav";
    soundFiles[22] = "audio/river.wav";
    soundFiles[23] = "audio/snow.wav";
    soundFiles[24] = "audio/avalanche.wav";

    float zero[3] = {0, 0, 0};
    int i;

    alListenerfv (AL_POSITION, zero);
    alListenerfv (AL_VELOCITY, zero);

    for (i=0; i<NUMBER_OF_SOUNDS; i++)
    {
        alGenSources (1, &(sources[i]));

        buffers[i] = alutCreateBufferFromFile (soundFiles[i].c_str());

        alSourcei (sources[i], AL_BUFFER, buffers[i]);
        alSourcef (sources[i], AL_GAIN, 1.0f);
        alSourcefv (sources[i], AL_POSITION, zero);
        alSourcei (sources[i], AL_LOOPING, AL_FALSE);
    }
   
    alSourcef (sources[i], AL_GAIN, 0.5f);

    alSourcePlay (0);
}

void processHits (GLint hits, GLuint buffer[])
{
	printf("\n\nnumber of hits: %i\n\n", hits);//number of objects under mouse cursor (hits/
	for (int i=0; i < hits; i++)
	{
		//printf("Number: %d\n", buffer[i*4]);//number hits selected, always one if using glLoadName()
		//printf("min Z: %d\n", buffer[i*4 + 1]);//min z
		//printf("max Z: %d\n", buffer[i*4 + 2]);//max z
		printf("Name of object on hit stack: %d \n", buffer[i*4 + 3]);//name of the hit
		//pickName[i] = buffer[i*4 + 3];		//name of object hit		
	}
		pickName = buffer[(hits-1)*4 + 3];
		printf("\n");			
}

void shapeNameLoad(int &name)
{
	glLoadName(name);
	name++;
}
void selectShapes(int x, int y)
{
	GLuint buffer[256] = {0};
	GLint hits, view[4];
 		
	glInitNames();						//Clear the name's stack, This stack contains all the info about the objects
 	glSelectBuffer(256, buffer);		//This chooses the buffer where the values are stored for the selection data
	glRenderMode(GL_SELECT);
 	glPushName(0);						//Now fill the stack with one element (or glLoadName will generate an error)
 
	//setup viewing for selection mode
	glGetIntegerv(GL_VIEWPORT, view);	//view[n] = 0.x, 1.y, 2.width, 3.height
 	glMatrixMode(GL_PROJECTION);

	//save original viewing matrix
	glPushMatrix();
	glLoadIdentity();

	gluPickMatrix(x, view[3]-y, 5.0, 5.0, view);	//pick area around cursor
		//gluPickMatrix(cursor_location x, cursor_location y,
		// picking area size w, picking area size h, 
		//current viewport(view[4]))
						
	glOrtho(-Width/2, Width/2, -Height/2, Height/2, -1.0, 1.0); //to be same clipping region as in reshape

	glMatrixMode(GL_MODELVIEW);
	
	if (menuSelection == 0)
	{
		buttonName = 1;
		shapeNameLoad(buttonName);
		drawPic(waterCycleMenu);
		shapeNameLoad(buttonName);
		drawPic(shooterMenu);
	}
	if (menuSelection == 1)
	{
		drawMenu();
		drawPlants();
	}
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

 	hits = glRenderMode(GL_RENDER);
	
	processHits(hits, buffer);
	glMatrixMode(GL_MODELVIEW);
}


void drawPic(objects object)
{
	//shapeNameLoad(buttonName);

	float x, y;
	float sx, sy;
	int dirX, dirY;
	int rotateX = 0;
	int rotateY = 0;

	object.translateScale(x, y, sx, sy);
	object.getDir(dirX, dirY);
	if (dirX == 1) rotateY = 0;
	else rotateY = 180;
	//if (dirY) rotateY = 0;
	//else rotateY = 180;

	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, object.bindTexture());
	glTranslatef(x, y, object.getPosZ());
	glScalef(sx, sy, 1.0f);
	
	glRotatef(rotateY, 0.0f, 1.0f, 0.0f);
	glRotatef(object.getRotation(), 0.0f, 1.0f, 0.0f);
	//glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);
	glRotatef(object.getRotationZ(), 0.0f, 0.0f, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, object.getAlpha());
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawBackground()
{
	//sun -100:400
	float x, y;
	sun.getPos(x, y);
	y *= .5;

	glPushMatrix();
	glColor4f(((100.0f-y)/255.0f), (127.0f/255.0f), (255.0f/255.0f), 1.0f);
	glTranslatef(0.0f, 210.0f, 1.0f);
	glScalef(505.0f, 300.0f, 1.0f);
    glBegin(GL_POLYGON);
   // glTexCoord2f(0.0f, 1.0f);	
	glVertex2f(-1.0f, 1.0f);
   // glTexCoord2f(1.0f, 1.0f);	
	glVertex2f(1.0f, 1.0f);
	//glTexCoord2f(1.0f, 0.0f);	
	glColor4f(((300.0f-y)/255.0f), (200.0f/255.0f), (255.0f/255.0f), 1.0f);
	glVertex2f(1.0f, -1.0f);
    //glTexCoord2f(0.0f, 0.0f);	
	glVertex2f(-1.0f, -1.0f);
    glEnd();
	glPopMatrix();
}

void drawStatPic(objects object, objects stat)
{	
	float x, y;
	float statX, statY;
	float sx, sy;
	int dirX, dirY;
	int rotateX = 0;
	int rotateY = 0;

	object.translateScale(x, y, sx, sy);
	object.getDir(dirX, dirY);
	stat.getPos(statX, statY);
	if (dirX == 1) rotateY = 0;
	else rotateY = 180;
	//if (dirY) rotateY = 0;
	//else rotateY = 180;

	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, object.bindTexture());
	glTranslatef(statX+x, statY+y, object.getPosZ());
	glScalef(sx, sy, 1.0f);
	
	glRotatef(rotateY, 0.0f, 1.0f, 0.0f);
	glRotatef(object.getRotation(), 0.0f, 1.0f, 0.0f);
	glColor4f(1.0f, 1.0f, 1.0f, object.getAlpha());
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawButton(float alpha, objects object)
{
	//button shape
	float x, y;
	float sx, sy;
	object.getPos(x, y);
	button[0].getScale(sx, sy);
	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, button[0].bindTexture());
	glTranslatef(x, y, 1.0f);
	glScalef(sx, sy, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawButton2(float alpha, objects object, objects stat)
{
	//button shape
	float x, y;
	float statX, statY;
	float sx, sy;
	stat.getPos(statX, statY);
	object.getPos(x, y);
	button[1].getScale(sx, sy);
	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, button[1].bindTexture());
	glTranslatef(statX+x, statY+y, 1.0f);
	glScalef(sx, sy, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawMenuButton(objects object)
{
	//back button
	drawButton(1.0f, object);
	//icon
	drawPic(object);//todo
	//button cover
	drawButton(0.3f, object);
}

void drawStatButton(objects object, objects stat)
{
	//back button
	drawButton2(1.0f, object, stat);
	//icon
	drawStatPic(object, stat);//todo
	//button cover
	//drawButton2(0.3f, object, stat);
}
void drawMenu( )
{
	//buttons
	buttonName = 3;
	shapeNameLoad(buttonName);
	drawMenuButton(sunButton);
	shapeNameLoad(buttonName);
	drawMenuButton(windButton);
	shapeNameLoad(buttonName);
	drawMenuButton(collectButton);
	shapeNameLoad(buttonName);
	drawMenuButton(rainButton);
	//shapeNameLoad(buttonName);
}
void drawPlants()
{
	shapeNameLoad(buttonName);
	if (drawPlant == 1)
		drawPic(plant[0]);//sprout
	else if (drawPlant == 2)
		drawPic(plant[1]);//grown plant sans fruit
	else if (drawPlant == 3)
		drawPic(plant[2]);//plant with fruit
	else if (drawPlant == 4)
		drawPic(plant[3]);//withered plant
	//printf("buttonName: %i\n", buttonName);
}

void drawHarvesting(){
	//harvest background
	float x, y;
	float sx, sy;
	float bsx, ba;
	harvest[0].getPos(x, y);
	harvest[0].getScale(sx, sy);

	//draw expanding box
	bsx = sx+(sx/10.0f)-5.0f;
	//printf("sx: %f\tsy: %f\n", sx, sy);
	glPushMatrix();
	glTranslatef(x, y, 1.0f);
	glScalef(bsx, bsx, 1.0f);//50:205
    glBegin(GL_POLYGON);	
	glColor4f(0.8f, 0.8f, 1.0f, 1.0f);
	glVertex2f(-1.0f, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glVertex2f(1.0f, 1.0f);
	glColor4f(1.0f, 0.8f, 0.8f, 1.0f);
	glVertex2f(1.0f, -1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glVertex2f(-1.0f, -1.0f);
    glEnd();
	glPopMatrix();

	//draw zoom in background
	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	if(drawHarvest == 0)
		glBindTexture(GL_TEXTURE_2D, harvest[0].bindTexture());
	if(drawHarvest == 1)
		glBindTexture(GL_TEXTURE_2D, harvest[1].bindTexture());
	glTranslatef(x, y, 1.0f);
	glScalef(sx, sy, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawStatCylinder(float alpha, objects stat){
	//stat shape
	float sx, sy;
	float statTranslateX, statTranslateY;
	stat.getScale(sx, sy);
	stat.getPos(statTranslateX, statTranslateY);
	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, stat.bindTexture());
	glTranslatef(statTranslateX, statTranslateY, 1.0f);
	glScalef(sx, sy, 1.0f);
	glColor4f(1.0f, 1.0f, 1.0f, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawRedBar(objects object, objects stat)
{
	float level, temp;
	object.getPos(level, temp);
	float x, y;
	stat.getPos(x, y);

	glPushMatrix();
	glTranslatef(x - 0.0f, y, 1.0f);
	glColor4f(1.0f, 0.0f, 0.0f, 0.4f);
    glBegin(GL_POLYGON);
	glVertex2f(-75.0f, 7.0f);
	glVertex2f(level, 7.0f);
	glVertex2f(level, -7.0f);
	glVertex2f(-75.0f, -7.0f);
    glEnd();
	glPopMatrix();
}

void drawStatLevel(objects stat, objects object)
{
	
	//back stat
	drawStatCylinder(0.7f, stat);

	//stat level - red bar
	drawRedBar(object, stat);
	//stat cover
	//drawStatCylinder(0.2f, object);

	//draw icon button button
	drawStatButton(object, stat);
}

void drawStats()
{

	drawStatLevel (statsLevel[0], cloudStat);//todo
	drawStatLevel (statsLevel[1], windStat);//todo
	drawStatLevel (statsLevel[2], plantGrowthStat);//todo
	drawStatLevel (statsLevel[3], snowStat);//todo
	//drawStatLevel windStat;//todo
}
void drawRiver()
{
	float x, y;
	float sx, sy;
	float rotZ = river.getRotationZ();
	float rot = river.getRotation();
	river.getScale(sx, sy);
	river.getPos(x, y);

	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	
	glBindTexture(GL_TEXTURE_2D, river.bindTexture());
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	glPushMatrix();
	glTranslatef(x, y, 1.0f);
	glRotatef(rotZ, 0.0f, 0.0f, 1.0f);
	glRotatef(rot, 0.0f, 1.0f, 0.0f);
	glScalef(sx, sy, 1.0f);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(x-50.0f, y+30.0f, 1.0f);
	glRotatef(rotZ, 0.0f, 0.0f, 1.0f);
	glRotatef(rot, 0.0f, 1.0f, 0.0f);
	glScalef(sx, sy, 1.0f);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	
	glPushMatrix();
	glTranslatef(x +50.0f, y, 1.0f);
	glRotatef(rotZ, 0.0f, 0.0f, 1.0f);
	glRotatef(rot, 0.0f, 1.0f, 0.0f);
	glScalef(sx, sy, 1.0f);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}
void drawScore()
{
	//score background
	glPushMatrix();
	glColor4f(0.5f, score1*.2, 1.0f - score1*.11, 1.0f);
	glTranslatef(183.0f, -460.0f, 1.0f);
	glScalef(45.0f, 35.0f, 1.0f);
    glBegin(GL_POLYGON);
    //glTexCoord2f(0.0f, 0.0f);	
	glVertex2f(-1.0f, -1.0f);   
	// glTexCoord2f(0.0f, 1.0f);	
	glVertex2f(-1.0f, 1.0f);
   // glTexCoord2f(1.0f, 1.0f);	
	glVertex2f(1.0f, 1.0f);
	glColor4f(score10*.11, score10*.11,  1.0f, 1.0f);
	//glTexCoord2f(1.0f, 0.0f);	
	glVertex2f(1.0f, -1.0f);
    glEnd();
	glPopMatrix();

	//one digit
	drawPic(onesScore);

	//tens digit
	drawPic(tensScore);
}

void drawWords(objects object)
{
	float x, y;
	float sx, sy;
	int dirX, dirY;
	int rotateX = 0;
	int rotateY = 0;

	object.translateScale(x, y, sx, sy);
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, object.bindTexture());

	glPushMatrix();
	glTranslatef(x, y, object.getPosZ());
	glScalef(sx, sy, 1.0f);
	float alpha =  object.getAlpha();
	glColor4f(0.0f, 0.0f, 0.0f, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();

	glScalef(1.02f, 1.02f, 1.0f);
	glColor4f(1.0f - alpha, alpha, alpha, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}

void drawBlackColorItem(objects object, int shiftX, int shiftY, float alpha)
{
	float x, y;
	float sx, sy;
	int dirX, dirY;
	int rotateX = 0;
	int rotateY = 0;

	object.translateScale(x, y, sx, sy);
	object.getDir(dirX, dirY);
	if (dirX == 1) rotateY = 0;
	else rotateY = 180;
	//if (dirY) rotateY = 0;
	//else rotateY = 180;

	glPushMatrix();
	glEnable(GL_TEXTURE_2D);    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, object.bindTexture());
	glTranslatef(x+shiftX, y+shiftY, object.getPosZ());
	glScalef(sx, sy, 1.0f);
	
	glRotatef(rotateY, 0.0f, 1.0f, 0.0f);
	glRotatef(object.getRotation(), 0.0f, 1.0f, 0.0f);
	//glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);
	glRotatef(object.getRotationZ(), 0.0f, 0.0f, 1.0f);
	glColor4f(0.0f, 0.0f, 0.0f, alpha);
	glBegin(GL_POLYGON);
	glTexCoord2f(0.0f, 1.0f);	glVertex2f(-1.0f, 1.0f);
	glTexCoord2f(1.0f, 1.0f);	glVertex2f(1.0f, 1.0f);
	glTexCoord2f(1.0f, 0.0f);	glVertex2f(1.0f, -1.0f);
	glTexCoord2f(0.0f, 0.0f);	glVertex2f(-1.0f, -1.0f);
	glEnd();
	glPopMatrix();
	glDisable(GL_BLEND);
}
void drawMainMenuItems()
{
		drawPic(background);
		drawBlackColorItem(title, 5, -5, 0.6);
		drawBlackColorItem(waterCycleMenu, 5, -5, 0.6);
		drawBlackColorItem(shooterMenu, 5, -5, 0.6);
		drawPic(title);
		drawPic(waterCycleMenu);
		drawPic(shooterMenu);
}

void drawTutorialSlides()
{

	if (drawTutorial == 1)drawPic(tutorial[0]);
	if (drawTutorial == 2)drawPic(tutorial[1]);
	drawWords(tutorial[2]);
	drawWords(tutorial[3]);
}

void display(void)
{ 
	if(menuSelection == 0){
		drawMainMenuItems();
		glutSwapBuffers();
		glClear(GL_COLOR_BUFFER_BIT);	
	}
	else if (menuSelection == 1)
	{
		drawMenu();
		drawStats();
		drawBackground();
		drawPic(sun);
		if(drawSnow < 4)
			drawPic(mountain[0]);
		else 
			drawPic(mountain[1]);
		if(drawSnow == 1)
			drawPic(snow[0]);
		if(drawSnow == 2)
			drawPic(snow[1]);
		if(drawSnow == 3)
			drawPic(snow[2]);
		if(drawSnow >= 4)
			drawPic(snow[3]);
		drawRiver();
		drawPic(cloud);
		drawHarvesting();
		drawPic(tree);
		drawPic(fish);
		drawPic(steam[0]);
		drawPic(steam[1]);
		drawPic(steam[2]);
		drawPic(wind);

		if(drawHouse != 2 && drawPlant != 4 && drawBunny < 5)
			drawPic(person[0]);//happy person
		else
			drawPic(person[1]);//mad person

		if (drawHouse == 1)
			drawPic(house[0]);//normal house

		drawPlants();

		if (drawBunny == 1)
			drawPic(bunny[0]);
		if (drawBunny == 2)
			drawPic(bunny[1]);
		if (drawBunny == 3)
			drawPic(bunny[2]);
		if (drawBunny == 4)
			drawPic(bunny[3]);
		if (drawBunny == 5 || drawBunny == 6)
			drawPic(bunny[4]);
		drawPic(rain);

		if (drawHouse == 2)
			drawPic(house[1]);//snow covered house
		
		//drawPic(sunBeam[0]);
		//drawPic(sunBeam[1]);
		//drawPic(sunBeam[2]);

		drawPic(snowFlake);
		if (drawSnow == 5)
			drawPic(avalanche);
		drawScore();
		drawTutorialSlides();
		drawWords(gameOver);

		glutSwapBuffers();
		glClear(GL_COLOR_BUFFER_BIT);	
	}
	else if (menuSelection == 2)
	{	
		Game game;
		game.OnExecute();
		menuSelection = 0;
	}
}

void Reshape(int w, int h)
{
	//if ((w*0.708) >= h)
		glViewport((w/2)-(h), 0,h*2,h );
	//else
		//glViewport((w/2)-(h), 0,h*2,h );
	glMatrixMode (GL_PROJECTION);
	glLoadIdentity ();
	glOrtho(-Width/2, Width/2, -Height/2, Height/2, -1.0, 2000.0); 
	//printf("w: %i\th:%i\n", w, h);
}

void setTextures()
{
	background.setTexture("images/titleScreen.png");
	waterCycleMenu.setTexture("images/WaterCycleLand.png");
	shooterMenu.setTexture("images/Shooter.png");
	title.setTexture("images/title.png");
	tutorial[0].setTexture("images/tutorial1.png");
	tutorial[1].setTexture("images/tutorial2.png");
	tutorial[2].setTexture("images/tutorial.png");
	tutorial[3].setTexture("images/skip.png");
	
	cloud.setTexture("images/cloud.png");
	rain.setTexture("images/rain.png");
	sun.setTexture("images/sun.png");
	tree.setTexture("images/tree.png");
	fish.setTexture("images/fish.png");
	plant[0].setTexture("images/plant1.png");
	plant[1].setTexture("images/plant2.png");
	plant[2].setTexture("images/plant3.png");
	plant[3].setTexture("images/plant4.png");
	steam[0].setTexture("images/steam.png");
	steam[1].setTexture("images/steam.png");
	steam[2].setTexture("images/steam.png");
	sunBeam[0].setTexture("images/sunBeam.png");
	sunBeam[1].setTexture("images/sunBeam.png");
	sunBeam[2].setTexture("images/sunBeam.png");
	wind.setTexture("images/wind.png");
	river.setTexture("images/ripple.png");
	mountain[0].setTexture("images/mountain.png");
	mountain[1].setTexture("images/mountain2.png");
	house[0].setTexture("images/house.png");
	house[1].setTexture("images/house2.png");
	snow[0].setTexture("images/snowCappedMountains1.png");
	snow[1].setTexture("images/snowCappedMountains2.png");
	snow[2].setTexture("images/snowCappedMountains3.png");
	snow[3].setTexture("images/snowCappedMountains4.png");
	snowFlake.setTexture("images/snowFlake.png");
	avalanche.setTexture("images/avalanche.png");
	person[0].setTexture("images/person1.png");
	person[1].setTexture("images/person2.png");
	buttonBack.setTexture("images/buttonBack2.png");
	button[0].setTexture("images/button.png");
	button[1].setTexture("images/button.png");
	windButton.setTexture("images/wind.png");
	sunButton.setTexture("images/sun.png");
	collectButton.setTexture("images/plant3.png");
	rainButton.setTexture("images/rain.png");
	harvest[0].setTexture("images/harvest1.png");
	harvest[1].setTexture("images/harvest2.png");
	bunny[0].setTexture("images/bunny1.png");
	bunny[1].setTexture("images/bunny2.png");
	bunny[2].setTexture("images/bunny1.png");
	bunny[3].setTexture("images/bunny2.png");
	bunny[4].setTexture("images/bunny1.png");

	statsLevel[0].setTexture("images/statsLevel.png");
	statsLevel[1].setTexture("images/statsLevel.png");
	statsLevel[2].setTexture("images/statsLevel.png");
	statsLevel[3].setTexture("images/statsLevel.png");
	cloudStat.setTexture("images/cloud.png");
	windStat.setTexture("images/wind.png");
	plantGrowthStat.setTexture("images/plant3.png");
	snowStat.setTexture("images/snowFlake.png");
	gameOver.setTexture("images/gameOver.png");
}

void resetAllParameters()
{
	//audio queues
    playBirds = 0;
    playAvalanche = 0;
    playSnow = 0;
    playBunny = 0;
    playBunnyEat = 0;
    playHarvest = 0;
    playNight = 0;
    playPlantWilt = 0;
    playRain = 0;
    playRiver = 0;
    playWind = 0;
    playZoomIn = 0;
    playZoomOut = 0;

	//tutorial and menu
	background.setPosScale( 0.0f, 0.0f, 500.0f, 500.0f);
	waterCycleMenu.setPosScale( -150.0f, -270.0f, 100.0f, 100.0f);
	shooterMenu.setPosScale(  150.0f, -270.0f, 100.0f, 100.0f);
	title.setPosScale(  0.0f, 0.0f, 300.0f, 200.0f);
	tutorial[0].setPosScale(  0.0f, 0.0f, 500.0f, 500.0f);//slide 1
	tutorial[1].setPosScale(  0.0f, 0.0f, 500.0f, 500.0f);//slide 2
	tutorial[2].setPosScale(  0.0f,  0.0f, 400.0f, 200.0f);//tutorial word
	tutorial[3].setPosScale(  0.0f,  450.0f, 300.0f, 50.0f);//skip
	
	//set positions and scales
	cloud.setPosScale( 450.0f, 400.0f, 170.0f, 100.0f);
	mountain[0].setPosScale( 0.0f, -0.0f, 510.0f, 420.0f);
	mountain[1].setPosScale( 0.0f, -0.0f, 510.0f, 420.0f);
	rain.setPosScale(  250.0f, 700.0f, 14.00f, 22.00f);
	river.setPosScale(  -150.0f, -175.0f, 4.00f, 30.00f);////////////////////////////
	sun.setPosScale(  420.0f, -100.0f, 80.0f, 100.0f);
	tree.setPosScale(  -470.0f, -65.0f, 20.0f, 60.0f);
	plant[0].setPosScale(  -100.0f, -120.0f, 8.0f, 10.0f);
	plant[1].setPosScale(  -100.0f, -115.0f, 12.0f, 15.0f);
	plant[2].setPosScale(  -100.0f, -113.0f, 12.0f, 18.0f);
	plant[3].setPosScale(  -100.0f, -113.0f, 12.0f, 18.0f);
	steam[0].setPosScale(  350.0f, -30.0f, 30.0f, 150.0f);
	steam[1].setPosScale(  300.0f, -30.0f, 30.0f, 150.0f);
	steam[2].setPosScale(  250.0f, -30.0f, 30.0f, 150.0f);
	wind.setPosScale( 550.0f, 300.0f, 10.0f, 100.0f);
	sunBeam[0].setPosScale( 450.0f, 100.0f, 10.0f, 180.0f);
	sunBeam[1].setPosScale( 420.0f, 100.0f, 10.0f, 180.0f);
	sunBeam[2].setPosScale( 390.0f, 100.0f, 10.0f, 180.0f);
	house[0].setPosScale( -60.0f, -80.0f, 20.0f, 42.0f);
	house[1].setPosScale( -61.0f, -107.0f, 38.0f, 33.0f);
	snow[0].setPosScale( -217.0f, 127.0f, 297.0f, 295.0f);
	snow[1].setPosScale( -217.0f, 127.0f, 297.0f, 295.0f);
	snow[2].setPosScale( -217.0f, 127.0f, 297.0f, 295.0f);
	snow[3].setPosScale( -217.0f, 127.0f, 297.0f, 295.0f);
	snowFlake.setPosScale( -130.0f, -700.0f, 14.0f, 14.0f);
	avalanche.setPosScale( -350.0f, 300.0f, 100.0f, 100.0f);
	person[0].setPosScale( -90.0f, -100.0f, 8.0f, 16.0f);
	person[1].setPosScale( -91.0f, -100.0f, 9.0f, 16.0f);
	harvest[0].setPosScale( -90.0f, -120.0f, 50.0f, 50.0f);
	harvest[1].setPosScale( -90.0f, -120.0f, 50.0f, 50.0f);
	bunny[0].setPosScale( -140.0f, -120.0f, 6.0f, 12.0f);
	bunny[1].setPosScale( -130.0f, -115.0f, 6.0f, 12.0f);
	bunny[2].setPosScale( -120.0f, -120.0f, 6.0f, 12.0f);
	bunny[3].setPosScale( -110.0f, -115.0f, 6.0f, 12.0f);
	bunny[4].setPosScale( -100.0f, -120.0f, 6.0f, 12.0f);

	//buttons
	buttonBack.setPosScale( 332.0f, -460.0f, 265.0f, 70.0f);
	button[0].setPosScale( 0.0f, 0.0f, 35.0f, 40.0f);
	sunButton.setPosScale( 263.0f, -460.0f, 17.0f, 20.0f);
	collectButton.setPosScale( 458.0f, -460.0f, 20.0f, 20.0f);
	rainButton.setPosScale( 393.0f, -460.0f, 17.0f, 26.0f);
	windButton.setPosScale( 328.0f, -460.0f, 20.0f, 30.0f);

	//stats
	statsLevel[0].setPosScale	(56.0f,  -460.0f, 80.0f, 10.0f);
	statsLevel[1].setPosScale	(-102.0f,  -460.0f, 80.0f, 10.0f);
	statsLevel[2].setPosScale	(-260.0f,  -460.0f, 80.0f, 10.0f);
	statsLevel[3].setPosScale	( -418.0f,  -460.0f, 80.0f, 10.0f);
	button[1].setPosScale		( 0.0f,    0.0f, 30.0f, 33.0f);
	cloudStat.setPosScale		( -50.0f, -0.0f, 20.0f, 20.0f);
	windStat.setPosScale		( -50.0f, -0.0f, 15.0f, 15.0f);
	plantGrowthStat.setPosScale	( -50.0f, -0.0f, 15.0f, 15.0f);
	snowStat.setPosScale		( -50.0f, -0.0f, 25.0f, 25.0f);

	//score
	tensScore.setPosScale	(163.0f,  -460.0f, 20.0f, 30.0f);
	onesScore.setPosScale	(203.0f,  -460.0f, 20.0f, 30.0f);
	gameOver.setPosScale	(0.0f,  200.0f, 400.0f, 200.0f);

	//mis settings
	cloud.setAlpha(0.0f);
	gameOver.setAlpha(0.0f);
	wind.setAlpha(0.0f);
	person[1].setRotation(180.0f);
	person[0].setRotation(180.0f);
	avalanche.setRotationZ(-45.0f);
	river.setRotationZ(252.0f);
	avalanche.setAlpha(1.0f);
	onesScore.setTexture("images/0.png");
	tensScore.setTexture("images/0.png");
	//tutorial[1].setAlpha(0.0f);
	tutorial[2].setAlpha(0.0f);
	tutorial[3].setAlpha(0.0f);

	//initialize global values
	drawPlant = 0;
	drawHouse = 1;
	harvesting = 0;
	drawSnow = 0;
	drawHarvest = 0;
	score1 = 0;
	score10 = 0;
	drawTutorial = 0;
}

void stopAllAudio()
{
	for (int i = 0; i < NUMBER_OF_SOUNDS; i++)
		stop(i);
}

static void Key(unsigned char key, int x, int y)
{ 
	switch (key) {
		case ESC:
			if (menuSelection == 0)
				exit(0);
			else
			{
				menuSelection = 0;
				resetAllParameters();	
				stopAllAudio();
			}
			break;
		case 'M':
			menuSelection = 0;
			stopAllAudio();
			break;		
		case 'm':
			menuSelection = 0;
			stopAllAudio();
			break;
		case SPACE:
			if (menuSelection == 1 && drawTutorial < 3)
				drawTutorial++;
			else{
				resetAllParameters();
				reset = 1;
				drawTutorial = 1;
			}
			break;
	}
}
void resizingForHarvest(float harvestScale){
	person[0].setPosScale( -90.0f+((harvestScale-1.0)*10), -100.0f+((harvestScale-1.0)*30), 8.0f*harvestScale, 16.0f*harvestScale);
	person[1].setPosScale( -91.0f+((harvestScale-1.0)*10), -100.0f+((harvestScale-1.0)*30), 9.0f*harvestScale, 16.0f*harvestScale);
	plant[0].setPosScale(  -100.0f+((harvestScale-1.0)*0), -120.0f+((harvestScale-1.0)*10), 8.0f*harvestScale, 10.0f*harvestScale);
	plant[1].setPosScale(  -100.0f+((harvestScale-1.0)*0), -115.0f+((harvestScale-1.0)*15), 12.0f*harvestScale, 15.0f*harvestScale);
	plant[2].setPosScale(  -100.0f+((harvestScale-1.0)*0), -113.0f+((harvestScale-1.0)*18), 12.0f*harvestScale, 18.0f*harvestScale);
	plant[3].setPosScale(  -100.0f+((harvestScale-1.0)*0), -113.0f+((harvestScale-1.0)*18), 12.0f*harvestScale, 18.0f*harvestScale);
	house[0].setPosScale( -60.0f+((harvestScale-1.0)*40), -80.0f+((harvestScale-1.0)*50), 20.0f*harvestScale, 42.0f*harvestScale);
	house[1].setPosScale( -61.0f+((harvestScale-1.0)*41), -107.0f+((harvestScale-1.0)*22), 38.0f*harvestScale, 33.0f*harvestScale);
	harvest[0].setPosScale( -90.0f+((harvestScale-1.0)*10), -120.0f+((harvestScale-1.0)*10), 50.0f*harvestScale, 50.0f*harvestScale);
	harvest[1].setPosScale( -90.0f+((harvestScale-1.0)*10), -120.0f+((harvestScale-1.0)*10), 50.0f*harvestScale, 50.0f*harvestScale);
	bunny[0].setPosScale( -140.0f-((harvestScale-1.0)*30), -120.0f+((harvestScale-1.0)*10), 6.0f*harvestScale, 12.0f*harvestScale);
	bunny[1].setPosScale( -130.0f-((harvestScale-1.0)*25), -115.0f+((harvestScale-1.0)*15), 6.0f*harvestScale, 12.0f*harvestScale);
	bunny[2].setPosScale( -120.0f-((harvestScale-1.0)*15), -120.0f+((harvestScale-1.0)*10), 6.0f*harvestScale, 12.0f*harvestScale);
	bunny[3].setPosScale( -110.0f-((harvestScale-1.0)*10), -115.0f+((harvestScale-1.0)*15), 6.0f*harvestScale, 12.0f*harvestScale);
	bunny[4].setPosScale( -100.0f+((harvestScale-1.0)*0), -120.0f+((harvestScale-1.0)*10), 6.0f*harvestScale, 12.0f*harvestScale);
}

void updateScoreTexture()
{
	switch(score1){
		case 0:
			onesScore.setTexture("images/0.png");
			printf("im here\n");
			break;
		case 1:
			onesScore.setTexture("images/1.png");
			break;
		case 2:
			onesScore.setTexture("images/2.png");
			break;
		case 3:
			onesScore.setTexture("images/3.png");
			break;
		case 4:
			onesScore.setTexture("images/4.png");
			break;
		case 5:
			onesScore.setTexture("images/5.png");
			break;
		case 6:
			onesScore.setTexture("images/6.png");
			break;
		case 7:
			onesScore.setTexture("images/7.png");
			break;
		case 8:
			onesScore.setTexture("images/8.png");
			break;
		case 9:
			onesScore.setTexture("images/9.png");
			break;
	}	
	switch(score10){
		case 0:
			tensScore.setTexture("images/0.png");
			break;
		case 1:
			tensScore.setTexture("images/1.png");
			break;
		case 2:
			tensScore.setTexture("images/2.png");
			break;
		case 3:
			tensScore.setTexture("images/3.png");
			break;
		case 4:
			tensScore.setTexture("images/4.png");
			break;
		case 5:
			tensScore.setTexture("images/5.png");
			break;
		case 6:
			tensScore.setTexture("images/6.png");
			break;
		case 7:
			tensScore.setTexture("images/7.png");
			break;
		case 8:
			tensScore.setTexture("images/8.png");
			break;
		case 9:
			tensScore.setTexture("images/9.png");
			break;
	}
}


bool isPlaying(int index)
{
    ALenum state;
    
    alGetSourcei(sources[index], AL_SOURCE_STATE, &state);
    
    return (state == AL_PLAYING);
}

void update(int value)
{
	float x, y;
	float sx, sy;
	int dirX, dirY;
	static int rainOn = 0;
	static int snowOn = 0;
	static float rainX, rainY;
	static float snowX, snowY;
	static float cloudSpeed = 0.0f;//4 max
	static float harvestScale = 1.0f;
	static float snowHitsGround = 350.f;
	static int timeInitialize = 1;
	static int riverTimeInitialize = 1;
	static int numberOfClouds = 0;
	static int riverSwirl = 6;
	static int tutorialAlphaIncrease = 1;
	static time_t timeStart, riverTimeStart;
	time_t timeEnd, riverTimeEnd;

	//reset static parameters
	if (reset){
		rainOn = 0;
		snowOn = 0;
		cloudSpeed = 0.0f;//4 max
		snowHitsGround = 350.f;
		reset = 0;
		timeInitialize = 1;
		tutorialAlphaIncrease = 1;
	}
	
	//play Audio
	if (menuSelection == 1 && drawTutorial > 2)
		playAudio();

	//tutorial
	if (drawTutorial == 1 || drawTutorial == 2)
	{
		float tutorialAlpha2 = tutorial[2].getAlpha();
		float tutorialAlpha3 = tutorial[3].getAlpha();
		if (tutorialAlpha2 > 1.0f)
			tutorialAlphaIncrease = 0;
		if (tutorialAlpha2 < 1.0f && tutorialAlphaIncrease) //tutorial word
			tutorial[2].setAlpha(tutorialAlpha2 + .02);	
		else
			tutorial[2].setAlpha(tutorialAlpha2 - .02);	
		if (tutorialAlpha3 < 1.0f) //skip
			tutorial[3].setAlpha(tutorialAlpha3 + .02);				
	}
	else  
	{
		tutorial[2].setAlpha(0.0f);				
		tutorial[3].setAlpha(0.0f);				
	}

	//gameover
	if(drawHouse == 2)
	{
		float gameOverAlpha = gameOver.getAlpha();
		if (gameOverAlpha < 1.0f) 
			gameOver.setAlpha(gameOverAlpha + .01);		
	}

	//river
	if(rainY == -110.0f){
		if(rainX <= 100)
			riverSwirl = 0;
	}
	if (riverSwirl < 6)
	{
		bool soundCheck = isPlaying(22);
		if (!soundCheck)
			playRiver = 1;
		//initialize time
		if (riverTimeInitialize){
			riverTimeStart = time (NULL);
			riverTimeInitialize = 0;
		}
		riverTimeEnd = time (NULL);
		if(((riverTimeEnd - riverTimeStart) > .1)){
			riverTimeInitialize = 1;
			float riverRot = river.getRotation();
			riverRot += 180;
			if (riverRot >= 360)
				riverRot = 0;
			river.setRotation(riverRot);
			riverSwirl++;
		}
		float riverSX, riverSY;
		river.getScale(riverSX, riverSY);//4, 30
		if (riverSwirl < 4 && riverSX < 4)
			river.setScale(riverSX+.05, riverSY+.35);
		else
			river.setScale(riverSX-.05, riverSY-.35);
	}
	else
	{
		river.setScale(0.0f, 0.0f);
	}

	//avalanche
	if (drawSnow == 5){
		float avalancheX, avalancheY;
		float avalancheSX, avalancheSY;
		avalanche.getPos(avalancheX, avalancheY);
		//play avalanche audio
		if (avalancheX <= -350.0f)	playAvalanche = 1;
		if (avalancheX < -100.0f)
		{	
			avalanche.setPos(avalancheX+4.0f, avalancheY-6.4f);	
		}
		else
		{
			avalancheSX = avalanche.getAlpha();
			if(avalancheSX > 0.0f)
				avalanche.setAlpha(avalancheSX-0.1f);
			//Avalanche GAMEOVER
			drawHouse = 2;
			drawPlant = 0;
		}
	}

	//bunny
	if(drawPlant == 3 || drawBunny >= 5)
	{
		//if plant becomes withereed make bunny disappear
		if (drawPlant == 4)
			drawBunny = 0;
		//initialize time
		if (timeInitialize){
			timeStart = time (NULL);
			timeInitialize = 0;
		}
		timeEnd = time (NULL);
		if(((timeEnd - timeStart) > .2) && drawBunny < 5){
			timeInitialize = 1;
			//change state of bunny
			//if (drawBunny < 6)
				drawBunny++;
				//bunny audio
				if (drawBunny%2 == 0) 
					playBunny = 1;
			//after plant is gone make bunny diappear
			if (drawPlant == 0)
				drawBunny = 0;
			//bunny has eaten plant
			if(drawBunny == 5){
				drawPlant = 0;
				playBunnyEat = 1;
			}
		}
		if(((timeEnd - timeStart) > 2) && drawBunny >= 5){
			//make bunny disappear after eating plant
			drawBunny = 0;
		}

	}
	else{
		drawBunny = 0;
		timeInitialize = 1;
	}

	//zoom in on house
	if(pickName == 5){
		if (harvesting == 0){
			harvesting = 1;
			playZoomIn = 1;
		}
		else {
			harvesting = 0;	
			playZoomOut = 1;
		}
		pickName = 0;
	}
	if (harvesting && harvestScale < 4.0f){
		harvestScale += 0.1f;
		resizingForHarvest(harvestScale);
		//resize objects
	}
	if (!harvesting && harvestScale > 1.0f){
		harvestScale -= 0.1f;
		if(harvestScale >= 1.0f)
			resizingForHarvest(harvestScale);
		//resize objects
	}

	//harvest plant for points
	if(pickName == 7){
		if(drawPlant == 3){
			drawPlant = 0;
			//play Audio
			playHarvest = 1;
			//add to score
			score1++;
			if (score1 > 9){
				score1 = 0;
				score10 ++;			
			}
			updateScoreTexture();
		}
		if(drawPlant == 4)
			drawPlant = 0;
	}

	//rain
	if( pickName == 6  && !rainOn){
		if(cloud.getAlpha() > 0.0f){
			//play rain audio
			bool soundCheck1 = isPlaying(11);
			bool soundCheck2 = isPlaying(12);
			bool soundCheck3 = isPlaying(13);
			bool soundCheck4 = isPlaying(14);
			bool soundCheck5 = isPlaying(15);
			if (!soundCheck1 && !soundCheck2 && !soundCheck3 && !soundCheck4 && !soundCheck5)
				playRain = 1;
	
			rainOn = 1;
			cloud.getPos(rainX, rainY);
			cloud.setAlpha(cloud.getAlpha()-0.25f);
			if(cloud.getAlpha() < 0.25f){
				cloud.setAlpha(0.0f);
				cloud.setPos(300.0, 400.0);
				numberOfClouds++;
			}
		}
	}
	//rain
	if (rainOn){
		rain.setPos(rainX, rainY);
		rainY -= 10.0f; 
		if (rainY <= -120.0f){
			rainOn = 0;
			rain.setPos(0.0f, 700.0f);
			//grow plants
			if (rainX > -125.0f && rainX < -75.0f){
				if (drawPlant < 4)
					drawPlant++;
				if (drawPlant == 4)
					playPlantWilt = 1;
			}
		}
	}

	//snow flakes
	if (snowOn)
	{
		bool soundCheck = isPlaying(23);
		if (!soundCheck){
			playSnow = 1;
			vol = 0.5f;
		}
		//snow leaves cloud, and cloud decreases alpha
		static int leftRight = 1;
		static float drift = 1.0f;
		if (snowY == 400.0f)
			cloud.setAlpha(cloud.getAlpha()-0.25f);
		snowFlake.setPos(snowX+drift, snowY);
		//adjust snow fall speed as it falls farther
		snowY -= 3.0f+(drawSnow); 
		//left/right motion of snow flakes
		drift += (2.0f*leftRight);
		//change left to right or vice versa if beyond bounds
		if (drift >= 20.0f || drift <= -20.0f)
			leftRight *= -1;

		//snow hits ground
		if (snowY <= snowHitsGround)
		{
			//reset statics for snow fall
			leftRight = 1;
			drift = 1.0f;

			//increase snow pack alpha
			if (drawSnow < 5)
			{
				drawSnow++;
				//Vary the length snow falls to the ground
				if (drawSnow < 4)
					snowHitsGround -= 150.0f;
			}
			//snow on valley ground
			if (drawSnow == 4)
				drawHarvest = 1;
			//next snow drops if cloud alpha greater than 0
			if(cloud.getAlpha() < 0.25f)
			{
				cloud.setAlpha(0.0f);
				snowOn = 0;
				snowFlake.setPos(0.0f, 700.0f);
				cloud.setPos(300.0, 400.0);
				snowHitsGround = 350.f;
			}
			cloud.getPos(snowX, snowY);
			if (snowX > 200.0) snowOn = 0;
		}
	}
	else{
		alSourcef (sources[23], AL_GAIN, vol);
		if (vol > 0.0f)vol -= 0.01f;
		if (vol <= 0.0f)
		{
			stop(23);
			alSourcef (sources[23], AL_GAIN, 0.5f);
		}
	}

	//wind
	if( pickName == 4){
		//check if sound p;aying, if not then play
		bool soundCheck1 = isPlaying(16);
		bool soundCheck2 = isPlaying(17);
		if (!soundCheck1 && !soundCheck2)
			playWind = 1;

		//wind image appears
		if (wind.getAlpha() < 1.0)
			wind.setAlpha(wind.getAlpha() + 0.02f);
		float windX, windY;
		float windSX, windSY;
		wind.getPos(windX, windY);
		wind.getScale(windSX, windSY);
		if (windX > 330.0f){
			wind.setPos(windX - 5.0f, windY);
		}
		if (windSX < 100.0f){
			wind.setScale(windSX + 2.0f, windSY);
	//wind.setPosScale( 550.0f, 300.0f, 10.0f, 100.0f);
		}
	}
	else{
		//wind image disappears
		float windX, windY;
		wind.getPos(windX, windY);
		if (wind.getAlpha() > 0.0f)
			wind.setAlpha(wind.getAlpha() - 0.05f);
		if (windX < 450.0f && wind.getAlpha() <= 0.0f){
			wind.setPosScale(550.0f, windY, 10.0f, 100.0f);
		}
	}

	//move cloud
	cloud.getPos(x, y);
	if( pickName == 4){
		if (x >= -300.0f){
			//if cloud is present then move to left
			if(cloud.getAlpha() > 0.0f)
				x-=cloudSpeed;
			//cloud speed increases
			if(cloudSpeed < (10.0f+score1+(10*score10)))
				cloudSpeed += 0.5f+(score1+(10*score10))*.1;
			
		}
		else{
			if (cloudSpeed > 10.0f)
				cloudSpeed = 10.0f;
			//cloud speed decreases
			if(cloudSpeed > 0.0f){
				x-=cloudSpeed;
				cloudSpeed -= (0.5f);
			}
		}
		cloud.setPos(x, y);
	}
	else{
		//cloud speed decreases
		if(cloudSpeed > 0.0f){
			//over mountian
			if (x <  -300.0f )
				cloudSpeed -= 0.5f;
			//not over mountian
			else
				cloudSpeed -= 0.25f;
			cloud.getPos(x, y);
			x-=cloudSpeed;
			cloud.setPos(x, y);
		}
	}
	//if cloud over mountain, dump snow
	if (x < -300.0f && !snowOn){
		snowOn = 1;
		cloud.getPos(snowX, snowY);
		snowFlake.setPos(snowX, snowY);
		numberOfClouds = 0;
	}

	//sun, steam
	if( pickName == 3){
		//sun
		sun.getPos(x, y);
		if (y < 400.0f) 
			y+=12.0f;
		sun.setPos(x, y);
		
		//bird audio
		if(y >= -101.0f)
			playBirds = 1;
		//stop night audio
		for(int i = 7; i <= 9; i++)
			stop(i);

		//steam and sun beams
		if (y >= 400.0f){
			//decrease snow level if multiple clouds are made
			if (numberOfClouds == 2 && drawSnow > 0){
				numberOfClouds = 0;			
				drawSnow--;
				if (drawHarvest == 1)
					drawHarvest = 0;
			}
			//steam
			float steamX, steamY;
			steam[0].getScale(sx, sy);
			if (sy <= 40.0f){
				sy = 40.0f;
			}
			if (sy < 140.0f){
				float steamAdjustment = 1.0f;
				sy += steamAdjustment;
				steam[0].getPos(steamX, steamY);
				steam[0].setScale(sx, sy);
				steam[1].setScale(sx, sy);
				steam[2].setScale(sx, sy);
				steam[0].setPos(350.0f, steamY + steamAdjustment);
				steam[1].setPos(300.0f, steamY + steamAdjustment);
				steam[2].setPos(250.0f, steamY + steamAdjustment);
			}
			if (sy > 138.0f){
				steam[0].setScale(10.0f, 40.0f);
				steam[1].setScale(10.0f, 40.0f);
				steam[2].setScale(10.0f, 40.0f);
				steam[0].setPos(350.0f, -50.0f);
				steam[1].setPos(300.0f, -50.0f);
				steam[2].setPos(250.0f, -50.0f);
			}

			//cloud response to sun
			float cx, cy;
			cloud.getPos(cx, cy);
			if (cloud.getAlpha() < 1.0f && cx > 100)
				cloud.setAlpha(cloud.getAlpha()+0.01f);
		}
		//no cloud yet
		if (y >= 400.0f && cloud.getAlpha() <= 0.01f)
			cloud.setPos(300.0f, 400.0f);
	}
	else{
		//sun
		sun.getPos(x, y);
		if (y > -100.0f) y-=3;
		sun.setPos(x, y);

		//play night/day audio
		if(y <= -100.0f){
			playNight = 1;
			//stop night audio
			static float volume = 1.0f;
			for(int i = 0; i <= 3; i++){
				alSourcef (sources[i], AL_GAIN, volume);				
			}
			volume -= 0.05f;
			if (volume <= 0.0f){
				volume = 1.0f;
				for(int i = 0; i <= 3; i++){
					stop(i);
					alSourcef (sources[i], AL_GAIN, volume);				
				}
			}

		}
		else
			playBirds = 1;


		//steam
		steam[0].setPosScale(350.0f, -50.0f, 10.0f, 0.0f);
		steam[1].setPosScale(300.0f, -50.0f, 10.0f, 0.0f);
		steam[2].setPosScale(250.0f, -50.0f, 10.0f, 0.0f);
		//sunbeam
		sunBeam[0].setScale(10.0f, 0.0f);
		sunBeam[1].setScale(10.0f, 0.0f);
		sunBeam[2].setScale(10.0f, 0.0f);

		//cloud
		if (cloud.getAlpha() < 0.2f && cloud.getAlpha() > 0.2f)
			cloud.setAlpha(0.25f);
	}

	//plant stats
	float plantStatX, plantStatY;
	plantGrowthStat.getPos(plantStatX, plantStatY);
	switch(drawPlant)
	{
		case(1):
			if (plantStatX < -17.0f)
				plantStatX += 0.5f;
			break;
		case(2):
			if (plantStatX < 16.0f)
				plantStatX += 0.5f;
			break;
		case(3):
			if (plantStatX < 50.0f)
				plantStatX += 0.5f;
			break;
		default:
			if (plantStatX > -50.0f)
				plantStatX -= 1.0f;
			break;
	}
	plantGrowthStat.setPos(plantStatX, 0.0f);	
		
	//wind stats
	float windStatX, windStatY;
	float windScaleStatX, windScaleStatY;
	windStat.getPos(windStatX, windStatY);
	wind.getScale(windScaleStatX, windScaleStatY);//10.0 - 100
	windScaleStatX = windScaleStatX - 60.0f;
	if (windStatX-10.0f > windScaleStatX){
		windStatX -= 5.0f;
		windStat.setPos(windStatX, 0.0f);
	}
	else
		windStat.setPos(windScaleStatX, 0.0f);
	
	//snow stats
	float snowStatX, snowStatY;
	snowStat.getPos(snowStatX, snowStatY);
	switch(drawSnow)
	{
		case(0):
			if (snowStatX > -50.0f)
				snowStatX -= 0.5f;
			break;
		case(1):
			if (snowStatX < -30.0f)
				snowStatX += 0.5f;
			break;
		case(2):
			if (snowStatX < -10.0f)
				snowStatX += 0.5f;
			break;
		case(3):
			if (snowStatX < 10.0f)
				snowStatX += 0.5f;
			break;
		case(4):
			if (snowStatX < 30.0f)
				snowStatX += 0.5f;
			break;
		case(5):
			if (snowStatX < 50.0f)
				snowStatX += 0.5f;
			break;
		default:
			if (snowStatX < 100.0f)
				snowStatX += 1.0f;
			break;
	}
	snowStat.setPos(snowStatX, 0.0f);	
	
	//cloud stats
	float cloudStatX, cloudStatY;
	float cloudStatAlpha;
	cloudStat.getPos(cloudStatX, cloudStatY);
	cloudStatAlpha = cloud.getAlpha();

	cloudStatAlpha = cloudStatAlpha*100 - 50;
	if (cloudStatX > cloudStatAlpha){
		cloudStatX -= 1.0f;
		cloudStat.setPos(cloudStatX, 0.0f);
	}
	else
		cloudStat.setPos(cloudStatAlpha, 0.0f);

	//fish
	fish.getPos(x, y);
	fish.getDir(dirX, dirY);
	x -= (0.5f*dirX);
	y += (0.3f*dirY);
	if(x < 100.0f || x > 480.0f) fish.changeDirX();
	if(y < -370.0f || y > -330.0f) fish.changeDirY();
	fish.setPos(x, y);

	glutPostRedisplay();
	glutTimerFunc(updateTimer, update, 0);
}


void mousePosition(int button, int state, int x, int y) 
{
	if ((state == GLUT_DOWN) && (button == GLUT_LEFT_BUTTON)) {
		selectShapes(x, y);
		//printf("mouseX; %i\tmouseY: %i\tpick name: %i\n", x, y, pickName);
		if (pickName >= 0 && menuSelection == 0)
			menuSelection = pickName;
		if (menuSelection == 1 && drawTutorial < 3)
			drawTutorial++;
		if(drawHouse == 2)
		{
			float gameOverAlpha = gameOver.getAlpha();
			if (gameOverAlpha >= 1.0f) 
			{
				resetAllParameters();
				reset = 1;
				drawTutorial = 1;
			}
		}
	}
	else
		pickName = 0;
}
void playAudio()
{
	srand ( time(NULL) );
	int playNumber;
	//static int test = 0;
	if (playBirds){ //0-3
		playNumber = rand() % 4;
		bool soundCheck = isPlaying(playNumber);
		if (!soundCheck)
			play(playNumber);
		playBirds = 0;
	}
	if (playBunny){ //4-5
		playNumber = rand() % 2 + 4;
		play(playNumber);
		playBunny = 0;
	}	
	if (playBunnyEat){ //20-21
		//playNumber = rand() % 2 + 20;
		play(20);
		playBunnyEat = 0;
	}
	if (playHarvest){ 
		play(6);
		playHarvest = 0;
	}
	if (playNight){ //7-9
		playNumber = rand() % 3 + 7;
		play(playNumber);
		playNight = 0;
	}
	if (playRiver){ //22
		//playNumber = rand() % 3 + 7;
		play(22);
		playRiver = 0;
	}
	if (playPlantWilt){ 
		play(10);
		playPlantWilt = 0;
	}
	if (playRain){ //11-15
		playNumber = rand() % 5 + 11;
		play(playNumber);
		playRain = 0;
	}
	if (playSnow){ 
		//playNumber = rand() % 5 + 11;
		play(23);
		playSnow = 0;
	}
	if (playWind){ //16-17
		playNumber = rand() % 2 + 16;
		play(playNumber);
		playWind = 0;
	}
	if (playAvalanche){ 
		//playNumber = rand() % 2 + 16;
		play(24);
		playAvalanche = 0;
	}
	if (playZoomIn){ 
		play(18);
		playZoomIn = 0;
	}
	if (playZoomOut){ 
		play(19);
		playZoomOut = 0;
	}
}

void lighting()
{
	//enable lighting
	GLfloat LightAmbient[] = {0.8f, 0.8f, 0.8f, 1.0f}; //changes ambient light not from light source
	GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 0.0f}; //intensity
	GLfloat LightSpecular[] = {0.0f, 0.0f, 0.0f, 1.0f}; //shiny material
	GLfloat LightPosition1[] = {0.0f, 0.0f, -3.0f, 1.0f}; 	

	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glShadeModel(GL_SMOOTH);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);
	glLightfv(GL_LIGHT0, GL_POSITION, LightPosition1);
	glEnable(GL_LIGHT0);
}

void init()										
{
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor ((0.0f), (0.0f), (0.0f), 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations

	lighting();

	//set all parameters
	resetAllParameters();
	fish.setPosScale(  250.0f, -350.0f, 10.0f, 15.0f);

	//set textures
	setTextures();

	//set audio
	setupAudio ();
}
int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE);
	glutInitWindowSize(Width, Height);
	glutCreateWindow("F.A.T.E.S.");
	alutInit (&argc, argv);

	init();
	
	//glutSetCursor(GLUT_CURSOR_INHERIT);
	glutKeyboardFunc(Key);
	glutReshapeFunc(Reshape); 
	glutDisplayFunc(display);
	glutMouseFunc(mousePosition);

	glutTimerFunc(updateTimer, update, 0);

	glutMainLoop();

	return 0 ;
}
